﻿package com.schimanek.animation 
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.errors.IllegalOperationError;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.getTimer;
	
	/**
	* ...
	* @author DefaultUser (Tools -> Custom Arguments...)
	*/
	public class Swinger 
	{
		public static var accThreshold				:Number = .5;
		public static var diffThreshold				:Number = .5;
		
		
		private static var _updater					:Sprite
		private static var _engineExists			:Boolean;		
		private static var _swingList				:Array;				
		
		private static  var time					:int = 0;
		
		public function Swinger() 
		{
			throw new IllegalOperationError("Swinger works static. Check those public methods");
		}
		/**
		 * Adds a new Tension Operation to the TensionList
		 * @param	oToSwing		The Object which Properties shall swing
		 * @param	aPropsToSwing	An Array of Strings of Properties to swing
		 * @param	oGoal			The Object whichs Properties are followed
		 * @param	aGoalProps		An Array of Strings of Properties to follow.
		 * @param	power			The Power of the Spring
		 * @param	damping			The Damping
		 * @param	aOffsets		An Array of numeric Offsets for the values
		 * @return					Returns the generated SwingListItem. Use to add EventListeners and maybe additional Stuff in the future
		 */
		public static function addSwing(oToSwing:Object, aPropsToSwing:Array, oGoal:Object, aGoalProps:Array, aOffsets:Array, power:Number = .5, damping:Number = .5):SwingListItem		
		{
			if (!_engineExists || !Boolean(_updater)) startEngine();
			
			var nTension:SwingListItem = new SwingListItem(oToSwing, aPropsToSwing, oGoal, aGoalProps, aOffsets, power, damping);
			if (isSwinging(oToSwing)) {
				//updateSwing(oToSwing, aPropsToSwing, oGoal, aGoalProps, aOffsets);
			}else{
				_swingList.push(nTension);
			}
			return nTension;
			//trace(_swingList);
		}
		
		static private function updateSwing(oToSwing:Object, aPropsToSwing:Array, oGoal:Object, aGoalProps:Array, aOffsets:Array):void
		{
			for (var t:uint = 0; t < _swingList.length;++t) 
			{				
				var tli:SwingListItem = _swingList[t] as SwingListItem;
				if (tli.oToSwing == oToSwing) {					
					//tli.updateSwingParams(aPropsToSwing, oGoal, aGoalProps, aOffsets);
				}
			}
		}
		
		static private function isSwinging(oToSwing:Object):Boolean
		{
			for (var t:uint = 0; t < _swingList.length;++t) 
			{	
				var tli:SwingListItem = _swingList[t] as SwingListItem;
				if (tli.oToSwing == oToSwing) {					
					return true;
				}
			}
			return false;
		}
		
		public static function removeSwing(oToSwing:Object):void {			
			//_swingList.splice(_swingList.indexOf(oToSwing), 1);
			
			var tli:SwingListItem
			for (var t:uint = 0; t < _swingList.length;++t) 
			{				
				tli= _swingList[t] as SwingListItem;
				if (tli.oToSwing == oToSwing) {
					_swingList.splice(t, 1);
					return;
				}
			}			
		}
		
		
		
		private static function update():void
		{
			var ti:uint = _swingList.length;			
			while (--ti>-1)
			{
				(_swingList[ti] as SwingListItem).update();				
				//ti--
			}
		}
		private static function startEngine():void {
			_engineExists = true;
			_swingList = new Array();
			
			_updater = new Sprite();
			_updater.addEventListener(Event.ENTER_FRAME, onEnterFrame);			
			
		}
		
		public static function pauseEngine():void {
			if(_updater!=null){
				_updater.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			}else {
				throw new IllegalOperationError("Swinger not running, pause failed");
			}
		}
		
		public static function unpauseEngine():void {
			_updater.addEventListener(Event.ENTER_FRAME, onEnterFrame);			
		}
		
		public static function togglePause():void {
			if(_updater.willTrigger(Event.ENTER_FRAME)) pauseEngine() else unpauseEngine()
		}
		
		static private function onEnterFrame(e:Event):void 
		{			
			update();
			time = getTimer() - time;
			
		}
	}
	
}